package cn.luzmzm.reqchecker.aspect;

import cn.luzmzm.reqchecker.annotations.SubmitChecke;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import cn.luzmzm.reqchecker.util.RedisUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
 * @projectName: ReqChecker
 * @package: cn.luzmzm.reqchecker.aspect
 * @className: SubmitCheckeAspect
 * @author: luzhimin
 * @description: 提交检查切面
 * @date: 2022/3/30 10:24
 */
@Component
@Aspect
@ConditionalOnBean({RedisTemplate.class})
public class SubmitCheckeAspect {

    @Autowired
    private RedisUtils reqCheckerRedisUtil;

    @Around("@annotation(sc)")
    public Object arround(ProceedingJoinPoint pjp, SubmitChecke sc) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String reqSubmit = (String) request.getSession().getAttribute("reqSubmitToken");
        if (reqSubmit==null){
            UUID uuid = UUID.randomUUID();
            request.getSession().setAttribute("reqSubmitToken",uuid.toString());
            System.out.println("requestURL"+request.getRequestURL());
            reqCheckerRedisUtil.set(uuid.toString()+request.getRequestURL(),1, sc.timeLimit());
            Object o = pjp.proceed();
            return o;
        }else {
            String key = reqSubmit + request.getRequestURL();
            if ( !reqCheckerRedisUtil.hasKey(key) ) {
                Object o = pjp.proceed();
                reqCheckerRedisUtil.set(key,1, sc.timeLimit());
                return o;
            } else {
                int time = (int)reqCheckerRedisUtil.get(key);
                time++;
                if(time>sc.time()){
                    //点了同样的URL继续限制，直到time次点击中间间隔超过了限制
                    reqCheckerRedisUtil.set(key,time,sc.timeLimit());
                    throw new RuntimeException(sc.message());
                }
                reqCheckerRedisUtil.set(key,time, sc.timeLimit());
                Object o = pjp.proceed();
                return o;
            }
        }
    }

}
